package info.vanbeem.WikiMindDesktop;

import java.io.File;
import java.io.IOException;

import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.Tree;

import swing2swt.layout.BorderLayout;
import swing2swt.layout.FlowLayout;

public class MainWindow {
	private static final String WINDOW_TITLE = "WikiMind Desktop 0.1";
	
	protected Shell shlWikimindDesktop;
	private Tree tree;
	private Settings settings = new Settings();
	private Text editor;
	private Browser browser;

	private FileTree fileTree;
	private FileViewer fileViewer;
	private EditorController editorController;
	
	Settings getSettings() {
		return settings;
	}

	void setSettings(Settings settings) {
		this.settings = settings;
	}

	FileViewer getFileViewer() {
		return fileViewer;
	}

	/**
	 * Launch the application.
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			MainWindow window = new MainWindow();
			window.open();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Open the window.
	 */
	public void open() {
		Display display = Display.getDefault();
		createContents();
		settings.getDimensions(shlWikimindDesktop);
		
		Menu menu = new Menu(shlWikimindDesktop, SWT.BAR);
		shlWikimindDesktop.setMenuBar(menu);
		
		MenuItem mntmMain = new MenuItem(menu, SWT.CASCADE);
		mntmMain.setText("Main");
		
		Menu menu_1 = new Menu(mntmMain);
		mntmMain.setMenu(menu_1);
		
		mntmSave = new MenuItem(menu_1, SWT.NONE);
		mntmSave .addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				editorController.save();
			}
		});
		mntmSave.setEnabled(false);
		mntmSave.setAccelerator(SWT.CTRL + 'S');
		mntmSave.setText("Save\tCtrl-S");
		
		MenuItem mntmSettings = new MenuItem(menu_1, SWT.NONE);
		mntmSettings.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				SettingsDialog dlg = new SettingsDialog(shlWikimindDesktop, SWT.None, getSettings());
				dlg.open();
			}
		});
		mntmSettings.setAccelerator(SWT.F2);
		mntmSettings.setText("Settings\tF2");
		
		MenuItem mntmView = new MenuItem(menu, SWT.CASCADE);
		mntmView.setText("View");
		
		Menu menu_2 = new Menu(mntmView);
		mntmView.setMenu(menu_2);
		
		MenuItem mntmRefresh = new MenuItem(menu_2, SWT.NONE);
		mntmRefresh.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				fileTree.fillTree();
			}
		});
		mntmRefresh.setAccelerator(SWT.F5);
		mntmRefresh.setText("Refresh\tF5");
		
		MenuItem mntmNextPane = new MenuItem(menu_2, SWT.NONE);
		mntmNextPane.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				if ( tree.isFocusControl() ) {
					tabFolder.setSelection(tbtmView);
					browser.setFocus();
				}
				else if ( browser.isFocusControl() ) {
					tabFolder.setSelection(tbtmEdit);
					editor.setFocus();
				}
				else if ( editor.isFocusControl() ) {
					tree.setFocus();
				}
			}
		});
		mntmNextPane.setAccelerator(SWT.F6);
		mntmNextPane.setText("Next pane\tF6");
		
		MenuItem mntmPreviousPane = new MenuItem(menu_2, SWT.NONE);
		mntmPreviousPane.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				if ( tree.isFocusControl() ) {
					tabFolder.setSelection(tbtmEdit);
					editor.setFocus();
				}
				else if ( browser.isFocusControl() ) {
					tree.setFocus();
				}
				else if ( editor.isFocusControl() ) {
					tabFolder.setSelection(tbtmView);
					browser.setFocus();
				}
			}
		});
		mntmPreviousPane.setAccelerator(SWT.F6 + SWT.SHIFT);
		mntmPreviousPane.setText("Previous Pane\tShift-F6");

		shlWikimindDesktop.open();
		shlWikimindDesktop.layout();
		while (!shlWikimindDesktop.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
	}

	/**
	 * Create contents of the window.
	 */
	protected void createContents() {
		shlWikimindDesktop = new Shell();
		shlWikimindDesktop.setSize(737, 475);
		shlWikimindDesktop.addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent e) {
				settings.setDimensions(shlWikimindDesktop);
				settings.setSelectedItem(activeFile == null ? "" : activeFile.getPath());
			}
		});
		shlWikimindDesktop.setText("WikiMind Desktop");
		shlWikimindDesktop.setLayout(new FillLayout(SWT.HORIZONTAL));
		
		SashForm sashForm = new SashForm(shlWikimindDesktop, SWT.NONE);
		
		tree = new Tree(sashForm, SWT.BORDER | SWT.FULL_SELECTION);
		
		Menu menu = new Menu(tree);
		tree.setMenu(menu);
		
		MenuItem mntmNew = new MenuItem(menu, SWT.NONE);
		mntmNew.setText("New\\tIns");
		
		MenuItem mntmRenametf = new MenuItem(menu, SWT.NONE);
		mntmRenametf.setText("Rename\\tF2");
		
		MenuItem mntmDelete = new MenuItem(menu, SWT.NONE);
		mntmDelete.setText("Delete\\tDel");
		
		tabFolder = new TabFolder(sashForm, SWT.NONE);
		
		tbtmView = new TabItem(tabFolder, SWT.NONE);
		tbtmView.setText("View");
		
		browser = new Browser(tabFolder, SWT.NONE);
		tbtmView.setControl(browser);
		
		tbtmEdit = new TabItem(tabFolder, SWT.NONE);
		tbtmEdit.setText("Edit");
		
		Composite composite = new Composite(tabFolder, SWT.NONE);
		tbtmEdit.setControl(composite);
		composite.setLayout(new BorderLayout(0, 0));
		
		Composite composite_1 = new Composite(composite, SWT.NONE);
		composite_1.setLayoutData(BorderLayout.NORTH);
		composite_1.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));
		
		final ToolBar toolBar = new ToolBar(composite_1, SWT.NONE);

		editor = new Text(composite, SWT.BORDER | SWT.WRAP | SWT.V_SCROLL | SWT.MULTI);
		editor.setEnabled(false);
		editor.setLayoutData(BorderLayout.CENTER);
		sashForm.setWeights(new int[] {146, 423});
		
		fileViewer = new FileViewer(this);
		editorController = new EditorController(this);
		fileTree = new FileTree(this);
		
		// Heading toolbar item
		final Menu headingmenu = new Menu (shlWikimindDesktop, SWT.POP_UP);
		for (int i = 1; i <= 5; i++) {
			final MenuItem item = new MenuItem (headingmenu, SWT.PUSH);
			item.setText ("Heading " + i + "\tCtrl-" + i);
			item.setAccelerator(SWT.CTRL | ('0' + i));
			item.setData(i);
			item.addListener (SWT.Selection, new Listener () {
				public void handleEvent (Event event) {
					editorController.setHeading((Integer)item.getData());
				}
			});		
		}
		Utils.buildPopupToolItem(toolBar, "Heading", headingmenu);

		// Font toolbar item
		Utils.buildPopupToolItem(toolBar, "Font", 
				new String[]{"Bold", "B", "**", "Italic", "I", "//", "Underline", "U", "__", "Strike", "-", "--"},
				new Listener() {
					public void handleEvent(Event event) {
						editorController.setFont((String)event.widget.getData());
					}
				}
		);

		// Enum toolbar item
		Utils.buildPopupToolItem(toolBar, "Enumeration",
				new String []{"Numbered", "7", "#", "Unnumbered", "8", "*"},
				new Listener() {
					public void handleEvent(Event event) {
						editorController.setEnumeration((String)event.widget.getData());
					}
				}
		);		
	}
		
	Tree getTree() {
		return tree;
	}
	
	Text getEditor() {
		return editor;
	}
	
	Browser getBrowser() {
		return browser;
	}

	EditorController getEditorController() {
		return editorController;
	}

	FileTree getFileTree() {
		return fileTree;
	}

	private File activeFile;

	File getActiveFile() {
		return activeFile;
	}

	void setActiveFile(File activeFile) {
		this.activeFile = activeFile;
		loadFile();
		setTitle();
	}

	private void loadFile() {
		final EditorController txt = getEditorController();
		final FileViewer viewer = getFileViewer();

	    String content = "";
		boolean ok = false;

		try {
	    	if (activeFile != null && activeFile.isFile()) {
	    		content = Utils.readFile(activeFile);
		        ok = true;
	    	}
	    } catch (IOException e) {
	        e.printStackTrace();
	    }		    
		
		txt.setText(content);
		txt.setEnabled(ok);
		viewer.setText(content);
	}

	private boolean fileIsChanged;
	private MenuItem mntmSave;

	private TabItem tbtmView;

	private TabItem tbtmEdit;

	private TabFolder tabFolder;

	public boolean isFileIsChanged() {
		return fileIsChanged;
	}

	public void setFileIsChanged(boolean fileIsChanged) {
		if ( mntmSave != null ) {
			this.fileIsChanged = fileIsChanged;
			mntmSave.setEnabled(fileIsChanged);
		}
		setTitle();
	}

	private void setTitle() {
		String title = WINDOW_TITLE;
		if ( activeFile != null ) {
			title += " - " + activeFile.getName();
			if ( isFileIsChanged() ) {
				title += "*";
			}
		}
		shlWikimindDesktop.setText(title);
	}
}
